#include "extOSCThread.h"
#include "QDebug"
#include "Global.h"


ExtOSCThread::ExtOSCThread(int port)
{
    this->receiveSocket = new UdpReceiveSocket(
            IpEndpointName( IpEndpointName::ANY_ADDRESS, port)
    );
    this->start();
    seqSendPort = 32254;
    //seqSendPort = 57120;
}

void ExtOSCThread::run() {
    listener = new MutaPacketListener();
    mux.AttachSocketListener(this->receiveSocket,listener);
    mux.RunUntilSigInt();
    exec();
}

UdpReceiveSocket* ExtOSCThread::getReceiveSocket() {
    return this->receiveSocket;
}

void ExtOSCThread::quitConnection() {
    if(Muta::ONLINE) {
        char buffer[1024];
        osc::OutboundPacketStream p( buffer, 1024 );
        p << osc::BeginMessage( "/removeSyncObject" )
          << qPrintable(Muta::userName+"MutaCursor")
            << osc::EndMessage;
        send("127.0.0.1",32243,p);
    }
    this->mux.AsynchronousBreak();
}

MutaPacketListener* ExtOSCThread::getListener()
{
    return listener;
}

void ExtOSCThread::send(QString address, int port, osc::OutboundPacketStream p) {
    this->receiveSocket->SendTo(
            IpEndpointName(
                qPrintable(address),
                port
                ),
            p.Data(),p.Size()
        );
}

void ExtOSCThread::attack(QString id, QString type, float val)
{
    char buffer[1024];
    osc::OutboundPacketStream p( buffer, 1024 );
    p << osc::BeginMessage( "/attack" ) << qPrintable(id) << qPrintable(type) << val << osc::EndMessage;
    send("127.0.0.1",
         seqSendPort,
         p);
    //qDebug() << type;
}

void ExtOSCThread::sustain(QString id, QString type, float val)
{
    char buffer[1024];
    osc::OutboundPacketStream p( buffer, 1024 );
    p << osc::BeginMessage( "/sustain" ) << qPrintable(id) << qPrintable(type) << val << osc::EndMessage;
    send("127.0.0.1",
         seqSendPort,
         p);
}

void ExtOSCThread::release(QString id, QString type, float val)
{
    char buffer[1024];
    osc::OutboundPacketStream p( buffer, 1024 );
    p << osc::BeginMessage( "/release" ) << qPrintable(id) << qPrintable(type) << val << osc::EndMessage;
    send("127.0.0.1",
         seqSendPort,
         p);
}

void ExtOSCThread::login()
{
    char buffer[1024];
    osc::OutboundPacketStream p( buffer, 1024 );
    p << osc::BeginMessage( "/login" ) << osc::EndMessage;
    send("127.0.0.1",32243,p);
}

void ExtOSCThread::addEvent(float x, float y, int layer, float length)
{
    char buffer[1024];
    osc::OutboundPacketStream p( buffer, 1024 );
    p << osc::BeginMessage( "/addSyncObject" )
        << qPrintable(Muta::getObjectID())
        << "e"
        << "e"
        << qPrintable(Muta::userName)
        << x
        << y
        << layer
        << length
        << osc::EndMessage;
    send("127.0.0.1",32243,p);
}
void ExtOSCThread::addLine(QString type,float x, float y, int layer)
{
    char buffer[1024];
    QString initControlPoints("0,0,");
    initControlPoints.append(QString().number(64));
    initControlPoints.append(",");
    initControlPoints.append(QString().number(0));
    if(type.compare("l")==0) {
        initControlPoints.append("&");
        initControlPoints.append(QString().number(32));
        initControlPoints.append(",");
        initControlPoints.append(QString().number(0));
    }

    osc::OutboundPacketStream p( buffer, 1024 );
    p << osc::BeginMessage( "/addSyncObject" )
        << qPrintable(Muta::getObjectID())
        << qPrintable(type)
        << qPrintable(type)
        << qPrintable(Muta::userName)
        << x
        << y
        << layer
        << qPrintable(initControlPoints)
        << osc::EndMessage;
    send("127.0.0.1",32243,p);
}

void ExtOSCThread::removeObject(QString objectID)
{
    char buffer[1024];
    osc::OutboundPacketStream p( buffer, 1024 );
    p << osc::BeginMessage( "/removeSyncObject" )
        << qPrintable(objectID)
        << osc::EndMessage;
    send("127.0.0.1",32243,p);
}

void ExtOSCThread::setSyncArg(QString objectID, int argNum, float value)
{
    char buffer[1024];
    osc::OutboundPacketStream p( buffer, 1024 );
    p << osc::BeginMessage( "/setSyncArg" )
        << qPrintable(objectID)
        << argNum
        << value
        << osc::EndMessage;
    send("127.0.0.1",32243,p);
}

void ExtOSCThread::setSyncArg(QString objectID, int argNum, int value)
{
    char buffer[1024];
    osc::OutboundPacketStream p( buffer, 1024 );
    p << osc::BeginMessage( "/setSyncArg" )
        << qPrintable(objectID)
        << argNum
        << value
        << osc::EndMessage;
    send("127.0.0.1",32243,p);
}

void ExtOSCThread::setSyncArg(QString objectID, int argNum, QString value)
{
    char buffer[1024];
    osc::OutboundPacketStream p( buffer, 1024 );
    p << osc::BeginMessage( "/setSyncArg" )
        << qPrintable(objectID)
        << argNum
        << qPrintable(value)
        //<< 1
        << osc::EndMessage;
    send("127.0.0.1",32243,p);
}

void ExtOSCThread::posChange(QString objectID, const QPointF &point)
{
    char buffer[1024];
    osc::OutboundPacketStream p( buffer, 1024 );
    p << osc::BeginMessage( "/setSyncArg" )
        << qPrintable(objectID)
        << 1
        << point.x()
        << 1
        << osc::EndMessage;
    send("127.0.0.1",32243,p);

    p.Clear();
    p << osc::BeginMessage( "/setSyncArg" )
        << qPrintable(objectID)
        << 2
        << point.y()
        << 1
        << osc::EndMessage;
    send("127.0.0.1",32243,p);
}

void ExtOSCThread::controlPointAdded(QString objectID, QString controlPointString)
{
    //qDebug() << controlPointString;
    char buffer[1024];
    osc::OutboundPacketStream p( buffer, 1024 );
    p << osc::BeginMessage( "/setSyncArg" )
        << qPrintable(objectID)
        << 4
        << qPrintable(controlPointString)
        << 1
        << osc::EndMessage;
    send("127.0.0.1",32243,p);
}

void ExtOSCThread::addUserCursor()
{
    char buffer[1024];
    osc::OutboundPacketStream p( buffer, 1024 );
    p << osc::BeginMessage( "/addSyncObject" )
      << qPrintable(Muta::userName+"MutaCursor")
      << "uc"
      << "uc"
      << qPrintable(Muta::userName)
      << 0.0
      << 0.0
      << osc::EndMessage;
    send("127.0.0.1",32243,p);
}

void ExtOSCThread::changeSendPort(int sendPort)
{
    qDebug() << "changed send port: " << sendPort;
    seqSendPort = sendPort;
}

